﻿using Account.Api.Client;
using Common.Api.Client;
using Common.Api.Dtos;
using Cyss.Core;
using Cyss.Core.Api;
using Cyss.Core.Api.Client;
using Cyss.Core.Cache;
using Cyss.Core.Infrastructure;
using Cyss.Core.RabbitMQ;
using Cyss.TaskManager.Infrastructure;
using Cyss.TaskManager.Models;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Order.Api.Client;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Cyss.TaskManager
{
    public partial class FormMain : Form
    {

        private int mi = 0;
        private bool TaskIsCancel = false;
        private List<TaskThreadView> taskThreadViews = new List<TaskThreadView>();
        private MainThread mainThread { set; get; }
        private RabbitMQService _rabbitMQService { set; get; }
        private System.Threading.Timer _timer;
        public FormMain()
        {
            InitializeComponent();
            this.dataGridViewMain.AutoGenerateColumns = false;
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            //异步加载
            Task.Run(InIt);
        }



        private void InIt()
        {
            Register();
            Loading();
            Task.Run(AutoRefreshTask);
            AutoRefreshTask();
            CreateMQService();
            Task.Run(AutoStartTask);
        }

        /// <summary>
        /// 注册所有配置服务
        /// </summary>
        private void Register()
        {
            var host = Host.CreateDefaultBuilder()
            .ConfigureServices((hostContext, services) =>
            {
                try
                {
                    services.AddSingleton<IApiToken, Infrastructure.ApiToken>();
                    services.RegisterClientConfig(hostContext.Configuration);
                    services.RegisterOrderClient();
                    services.RegisterAccountClient();
                    services.RegisterCommonClient();

                    services.AddSingleton<IRabbitMQPersistentConnection, DefaultRabbitMQPersistentConnection>();
                    services.AddSingleton<RabbitMQService>();

                    services.AddSingleton<IRedisConnectionWrapper, RedisConnectionWrapper>();
                    services.AddSingleton<IStaticCacheManager, RedisCacheManager>();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

            }).Build();

            host.Services.RegisterServiceProvider();
        }

        private async void Loading()
        {
            GetLocaTaskThread();
            await GetDataBaseTaskThread();
            this.dataGridViewMain.Invoke(new Action(delegate
            {
                this.dataGridViewMain.DataSource = taskThreadViews;
            }));
        }

        /// <summary>
        /// 定时自动开启任务
        /// </summary>
        private void AutoStartTask()
        {
            int countMi = 2 * 60;
            while (mi < countMi)
            {
                if (TaskIsCancel)
                {
                    return;
                }
                int sy = countMi - mi;
                btnAutoService.Invoke(new Action(delegate
                {
                    btnAutoService.Text = $"{sy / 60}分{sy % 60}秒后程序将自动开启所有服务，点击此按钮可以关闭！";
                }));
                System.Threading.Thread.Sleep(1000);
                mi++;
            }
            if (mainThread == null)
            {
                btnStart.Enabled = false;
                btnClose.Enabled = true;
                mainThread = new MainThread(this.taskThreadViews);
                mainThread.Start();
            }
            btnAutoService.Invoke(new Action(delegate
            {
                btnAutoService.Visible = false;
            }));
        }

        /// <summary>
        /// 定时刷新任务状态
        /// </summary>
        private void AutoRefreshTask()
        {
            //每5分钟主动去查询任务
            _timer = new System.Threading.Timer(TimerHandler, null, 1000 * 60 * 5, 1000 * 60 * 5);

        }

        /// <summary>
        /// 每秒执行一次
        /// </summary>
        /// <param name="state"></param>
        private async void TimerHandler(object state)
        {
            _timer.Change(-1, -1);
            await GetDataBaseTaskThread();
            _timer.Change(1000 * 60 * 5, 1000 * 60 * 5);
        }

        /// <summary>
        /// 监听服务状态改变
        /// </summary>
        private void CreateMQService()
        {
            _rabbitMQService = IOCEngine.Resolve<RabbitMQService>();
            _rabbitMQService.CreateConsumer<int>("EditTaskStatus", StateChange);
        }
        private async void StateChange(int TaskId)
        {
            await GetDataBaseTaskThread();
        }

        /// <summary>
        /// 获取数据库任务
        /// </summary>
        private async Task GetDataBaseTaskThread()
        {
            try
            {
                var operateResult = await CommonClientFactory.Task.GetPageListTasks(new Common.Api.Dtos.TaskSearchModel());
                if (operateResult.IsSuccess == false)
                {
                    return;
                }
                var tasks = operateResult.Data.Data;

                var operateResultApiService = await CommonClientFactory.ApiService.GetApiServices();
                if (operateResultApiService.IsSuccess == false)
                {
                    return;
                }

                var operateResultConfig = await CommonClientFactory.Task.GetPageListTaskConfigs(new TaskConfigSearchModel());
                if (operateResultConfig.IsSuccess == false)
                {
                    return;
                }
                var configs = operateResultConfig.Data.Data;

                foreach (var task in tasks)
                {
                    var taskThread = taskThreadViews.FirstOrDefault(x => x.Id == task.Id);
                    if (taskThread != null)
                    {
                        taskThread.State = task.Status;
                        taskThread.Config = configs.FirstOrDefault(x => x.TaskId == taskThread.Id);
                        taskThread.Counter = task.Count;
                        taskThread.ConfigChange();
                        continue;
                    }

                    var apiService = operateResultApiService.Data.FirstOrDefault(x => x.Id == task.ApiServiceId);
                    if (apiService == null)
                    {
                        continue;
                    }

                    var service = new UrlService(apiService.BaseAddress);
                    service.TaskId = task.Id;
                    service.ServiceName = task.Name;
                    service.Url = task.Url;

                    TaskThreadView taskThreadView = new TaskThreadView();
                    taskThreadView.Counter = task.Count;
                    taskThreadView.State = task.Status;
                    taskThreadView.dgv = this.dataGridViewMain;
                    taskThreadView.UrlService = service;
                    taskThreadView.ServiceName = task.Name;
                    taskThreadView.Id = task.Id;
                    taskThreadView.Config = configs.FirstOrDefault(x => x.TaskId == taskThreadView.Id);
                    taskThreadView.Interval = taskThreadView.Config.Interval;

                    taskThreadViews.Add(taskThreadView);

                }

            }
            catch (Exception ex)
            {

            }
        }

        /// <summary>
        /// 获取本地任务
        /// </summary>
        /// <returns></returns>
        private IEnumerable<TaskThreadView> GetLocaTaskThread()
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
             .SelectMany(a => a.GetTypes().Where(t => t.BaseType == typeof(IService)))
             .ToArray();

            Assembly assembly = Assembly.GetExecutingAssembly();

            taskThreadViews.OrderBy(x => x.DisplayOrder);

            foreach (var type in types)
            {
                var enable = type.GetCustomAttribute<ServiceEnableAttribute>();
                if (enable == null)
                {
                    continue;
                }
                var typeInstance = assembly.CreateInstance(type.FullName) as IService;
                TaskThreadView taskThreadView = new TaskThreadView();
                taskThreadView.dgv = this.dataGridViewMain;
                taskThreadView.TaskType = type;
                taskThreadView.ServiceName = typeInstance.ServiceName;
                taskThreadView.Interval = typeInstance.Interval;
                taskThreadView.Id = typeInstance.TaskId;

                taskThreadViews.Add(taskThreadView);
            }
            return taskThreadViews;
        }

        private void FormMain_SizeChanged(object sender, EventArgs e)
        {
            dataGridViewMain.Columns[6].Width = 150;
            dataGridViewMain.Columns[7].Width = 150;

            if (this.WindowState == FormWindowState.Minimized)
            {
                this.Hide();
                this.notifyIconMain.Visible = true;
            }
        }

        private void dataGridViewMain_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            //点击开启关闭服务按钮
            if (dataGridViewMain.Columns[e.ColumnIndex].DataPropertyName == "ButtonTitle")
            {
                var task = dataGridViewMain.Rows[e.RowIndex].DataBoundItem as TaskThreadView;
                if (task.State == false && task.Colseing == false)
                {
                    task.State = true;
                    UpdateTaskStatus(task.Id, task.State);
                }
                else
                {
                    if (task.State == true && task.Colseing != true)
                    {
                        task.State = false;
                        UpdateTaskStatus(task.Id, task.State);
                    }
                }
            }

            //点击日志按钮
            if (dataGridViewMain.Columns[e.ColumnIndex].DataPropertyName == "ButtonLogTitle")
            {
                var task = dataGridViewMain.Rows[e.RowIndex].DataBoundItem as TaskThreadView;
                FormLog formLog = new FormLog(task.Id);
                formLog.Show();
            }

            //点击配置按钮
            if (dataGridViewMain.Columns[e.ColumnIndex].DataPropertyName == "ButtonConfigTitle")
            {
                var task = dataGridViewMain.Rows[e.RowIndex].DataBoundItem as TaskThreadView;
                FormTaskConfig formLog = new FormTaskConfig(task.ServiceName, task, task.Config);
                formLog.Show();
            }

            //点击配置按钮
            if (dataGridViewMain.Columns[e.ColumnIndex].DataPropertyName == "ButtonExecuteTitle")
            {
                var dialogResult = MessageBox.Show("确认立即执行任务吗！", "系统提示", MessageBoxButtons.OKCancel);
                if (dialogResult == DialogResult.OK)
                {
                    var task = dataGridViewMain.Rows[e.RowIndex].DataBoundItem as TaskThreadView;
                    if (task.IsRuning == false)
                    {
                        task.ExecuteAsync();
                    }
                }
            }
        }

        private async void UpdateTaskStatus(int taskId, bool Status)
        {
            var operateResult = await CommonClientFactory.Task.GetTaskById(taskId);
            operateResult.Data.Status = Status;
            await CommonClientFactory.Task.EditTask(operateResult.Data);
        }

        private void FormMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            var dialogResult = MessageBox.Show("确认关闭吗！", "系统提示", MessageBoxButtons.OKCancel);
            if (dialogResult == DialogResult.OK)
            {
                TaskIsCancel = true;
                if (mainThread != null)
                {
                    mainThread.Stop();
                }
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void notifyIconMain_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.notifyIconMain.Visible = false;
        }

        private void notifyIconMain_Click(object sender, EventArgs e)
        {
            this.Visible = true;
            this.WindowState = FormWindowState.Normal;
            this.notifyIconMain.Visible = false;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            btnStart.Enabled = false;
            btnClose.Enabled = true;
            if (mainThread == null)
            {
                mainThread = new MainThread(this.taskThreadViews);
                mainThread.Start();
            }
        }
        private void btnClose_Click(object sender, EventArgs e)
        {
            var dialogResult = MessageBox.Show("确认关闭后台服务吗！", "", MessageBoxButtons.OKCancel);
            if (dialogResult == DialogResult.OK)
            {
                btnStart.Enabled = true;
                btnClose.Enabled = false;
                if (mainThread != null)
                {
                    mainThread.Stop();
                }
            }
        }

        private void btnAutoService_Click(object sender, EventArgs e)
        {
            TaskIsCancel = true;
            btnAutoService.Visible = false;
        }


    }
}
